/*
* --------------------------------------
* Functions that manipulates the objects
* CRUD, Search
* --------------------------------------
* 
* nomenclature
* ------------
* display+...: write in the DOM
*
*/


function ObjectManager()
{
	// singleton
	if ( ObjectManager.prototype._singletonInstance ) {
	      return ObjectManager.prototype._singletonInstance;
	}
	ObjectManager.prototype._singletonInstance = this;
	
	var page = null; // indicate the current page (m: ulist)
	var sortBy = 'distance'; // kind of object sortin
	var items = []; // "items" array, contains all the "item" objects
	
	var imgURL = new Array(); // contain all the url of the pictures uploaded
	var fileCount = 0; // count the number of files uploaded
	
	/*
	 *  PUBLIC
	 */
	
	this.getItems = function()
	{
		return items;
	};
	
	/*
	 *  PUBLIC
	 *  Change the current page value
	 */
	this.setPage = function(newPage)
	{
		page = newPage;
	};
	
	/*
	 * PRIVATE
	 * Get data from item(s) the BDD in a JSON format
	 */
	function get(mode, id, bounds) 
	{
		switch(mode)
		{
			// load object with geographical bounds
			case 'bounds' : url = BASEPATH+'object/get_bounds/'; var data = bounds; console.log(bounds); break;
			// load only user item
			case 'user' : url = BASEPATH+'object/get_user/'; break;
			// load only one iten
			case 'item' : url = BASEPATH+'object/get_item/'+id; break;
		}
		
		
		$.ajax({
			type: 'POST',
			url: url,
			data: { data : data },
			timeout: 3000,
			success: function(data)
			{
				console.log(data);
				
				// update the array
				// make sure we reset the array
				items = []; 
				// push all items retrieved
				push(data);
				
				// refresh list 
				displayList(sortBy);
				// display markers on map
				MapManager.displayOnMap();
				
				// display success message
				display_alert('list updated', '#alert_area', 'success');
				console.log('get(): success');
			},
			error: function() { display_alert('connexion problem', '#alert_area', 'error'); console.log('get(): error'); }
		});
		switchInterface('content');
	};
	
	/*
	 *  PRIVATE
	 *  Empty and update the array 'items' from JSON formatted data
	 *  data : JSON format
	 */
	function push(data)
	{
		$.each(data, function(index, array) // create the array, index count the iterations, array is the content
		{
			var id = array['id'];
			var item = new Thing(array); // create an item and give it the array with the content
			items[id] = item; // the associative array "items" collects all the items by id
		});
		
		console.log('pushItem(): success');
	};
	
	
	/*
	 * PRIVATE
	 * Create an item in the BDD
	 */
	function object_create() {
		
		//debugger;
		var title = $('#title').val();
	    var price = $('#price').val();
	    var description = $('#description').val();
	    var lat = registrationMarker.getLatLng().lat;
	    var lng = registrationMarker.getLatLng().lng;
	    var terms = $('#terms').val();

	    //if(imgURL.length === 0)
	    if(imgURL == null)
	    	{ imgURL = 'empty'; }
	    else
	    	{ imgURL = imgURL.toString(); }

		$.ajax({
			type: 'POST',
			url: 'object/create',
			data: {'uid': uid, 'title': title, 'description': description, 'price': price, 'lat': lat, 'lng': lng, 'terms' : terms, 'imgURL': imgURL},
			timeout: 3000,
			success: function(data) {
				if(data == 'success')
				{
					ObjectManager.get();
					registrationMarker.closePopup();
		    		registrationLayer.clearLayers();
		    		cancelRegistration();
		    		display_alert('The item has been added', '#alert_area', 'success');
				}
				else if(data == 'fail_login')
				{
					display_alert('You must be logged to add an item', '#alert_area', 'error');
				}
				else if(data == 'fail_form')
				{
					display_alert('You wrote something wrong', '#alert_area', 'error');
				}
				else
				{
					display_alert('The item hasn\'t been added', '#alert_area', 'error');
				}
			},
	        error: function() { display_alert('connexion problem', '#alert_area', 'error'); }
		});
		
		// reset the array containing the url of the uploaded picture
		imgURL.length = 0;
		//imgURL = null;
	};
	
	this.init_object_create = function(manualuploader) {
		if(fileCount > '0')
		{
			manualuploader.fineUploader('uploadStoredFiles');
		}
		else
		{
			object_create();
		}
	};

	this.initRegistration = function() {
	    map.addEventListener('click', onMapClick);
	    document.body.style.cursor = 'crosshair';
	    $('#add_object_button').html('Cancel');
	    $("#content").prepend('<div id="register_area" class="well">Choose a location on the map</div>');
	    $("#main_header").hide();
	    $("#main_content").hide();
	    return false;
	};

	this.cancelRegistration = function() {
	    document.body.style.cursor = 'default';
	    map.removeEventListener('click', onMapClick);
	    $('#add_object_button').html('Add an object');
	    registrationMarker.closePopup();
	    registrationLayer.clearLayers();
	    firstClick = true;
	    $("#register_area").hide();
	    $("#main_header").show();
	    $("#main_content").show();
	    display_alert('registration has been canceled', '#alert_area', 'error');
	};

/*
 *Update object 
 */

	this.init_update = function(thing_id) {
	
		var thing = ObjectManager.items[thing_id];
		
		// leaflet
		cancel_onMoveEnd();
		if(thing.marker != null)
		{
			thing.marker.unbindPopup();
			thing.marker.bindPopup('You can now move your object!').openPopup();
			thing.marker.dragging.enable();
		}
		//debugger;
		//display the form
		msg = '<img class="photo img-polaroid" src="assets/uploads/'+displayPhoto(thing.uid, thing.imgURL)+'">'
		+ '<form id="form_object_update" method="post" accept-charset="utf-8" >'
		+ '	<label>Title</label><input type="text" id="title" name="title" value="'+thing.title+'" size="30" />'
		+ '	<label>Price</label><input type="text" id="price" name="price" value="'+thing.price+'" size="30" />' 
		+ '	<label>Description</label><textarea id="description" name="description">'+thing.description+'</textarea><br/>'
		+ ' 	<button type="submit" class="btn btn-primary" onclick="object_update('+thing.id+');return false;">Save changes</button>'
		+ ' 	<button type="button" class="btn" onclick="cancel_update('+thing.id+');return false;">Cancel</button>'
		+ '</form>';
		
		$('#'+thing.id).html(msg);
	};

	this.cancel_update = function(thing_id)
	{
		var thing = ObjectManager.items[thing_id];
		
		// leaflet
		init_onMoveEnd();
		
		thing.marker.closePopup();
		thing.marker.dragging.disable();
		
		displayList('distance');
	};

	function object_update(thing_id) {
		
		// get the object
		var thing = ObjectManager.items[thing_id];
		
		//debugger;
		var title = $('#title').val();
	    var price = $('#price').val();
	    var description = $('#description').val();
	    var lat = thing.marker.getLatLng().lat;
	    var lng = thing.marker.getLatLng().lng;
	    /*var lat = registrationMarker.getLatLng().lat;
	    var lng = registrationMarker.getLatLng().lng;*/
	    
	    //if(imgURL.length === 0)
	    if(imgURL == null)
	    	{ imgURL = 'empty'; }
	    else
	    	{ imgURL = imgURL.toString(); }
	
		$.ajax({
			type: 'POST',
			url: 'object/update',
			data: {'id' : thing_id, 'title': title, 'description': description, 'price': price, 'lat': lat, 'lng': lng, 'imgURL': imgURL},
			timeout: 3000,
			success: function(data) {
				if(data == 'success')
				{
					ObjectManager.get();
					/*registrationMarker.closePopup();
		    		registrationLayer.clearLayers();*/
		    		cancelRegistration();
		    		display_alert('The item has been added', '#alert_area', 'success');
				}
				else if(data == 'fail_login')
				{
					display_alert('You must be logged to add an item', '#alert_area', 'error');
				}
				else if(data == 'fail_form')
				{
					display_alert('You wrote something wrong', '#alert_area', 'error');
				}
				else
				{
					display_alert('The item hasn\'t been added', '#alert_area', 'error');
				}
			},
	        error: function() { display_alert('connexion problem', '#alert_area', 'error'); }
		});
		
		// reset the array containing the url of the uploaded picture
		imgURL.length = 0;
	};

/*
 * Delete an object
 */

	this.set_delete = function(thing_id)
	{
		$('#'+ thing_id).attr('status', 'delete');
	};

	this. init_delete = function()
	{
		$('[status="delete"]').each(function(i, e) {
			object_delete($(e).attr('id'));
		});
	};

	function object_delete(id)
	{
		$.ajax({
			type: 'GET',
			url: 'object/delete/'+id,
			timeout: 3000,
			success: function(data) {
			if(data == 'success')
			{
				display_alert('the item has been deleted', '#alert_area', 'success');
				ObjectManager.get();
				displayList(sortBy);
			}
			else
			{
				display_alert('the item hasn\'t been deleted', '#alert_area', 'error');
			}
		},
	        error: function() { display_alert('connexion problem', '#alert_area', 'error'); }
		});
	};

/*
 * Search an object
 */

	this.object_search = function(string) {
		
		if(ObjectManager.ObjectManager.page == 'm')
		{
			domElem = '#mobject_list';
		}
		else
		{
			domElem = '#object_list';
		}
		
		
		$.ajax({
			type: 'POST',
			url: 'object/search',
			data: {'string': string, 'param': ObjectManager.page},
			timeout: 3000,
			success: function(data) {
				$(domElem).empty();
				if(!jQuery.isEmptyObject(data) && data != 'fail_form')
		    	{
					ObjectManager.updateitems(data);
					displayList(ObjectManager.sortBy);
					displayOnMap;
		    	}
		    	else
		    	{
		    		$(domElem).html('not found...');
		    	}
			},
	        error: function(data) { display_alert('connexion problem', '#alert_area', 'error'); }
		});
	};

/*
 * Refresh the object list
 * 
 * mapCenter: actual position of the user - array [lat, lng]
 * ObjectManager.sortBy : kind of sorting distance or price
 */



	function displayListItem(item)
	{
		var msg = '<div class="object">'
		+ '<div id="' + item.id + '" class="object_info" onclick="MapManager.locate(' + item.id + ');">'
			+ '<img class="photo img-polaroid" src="'+BASEPATH+'assets/uploads/'+displayPhoto(item.uid, item.imgURL)+'">'
			+ '<strong>' + item.title + '</strong><br/>'
			+ 'Image <img src="https://graph.facebook.com/gauthier.vdp/picture"/>';
			if(page != 'm')
			{
				msg += ' by ' + item.uid + '<br />';
			}
			msg += '' + item.description + '<br />'
			//+ ' : ' + item.price + ' euros<br />
			+ '<span class="distance">' + displayDistance(item.distance) + '</span> away - '
			+ displayDate(item.added) + ' ago<br/>'
			+ '<a href="item/'+ item.id + '">Expand object</a>'
			+ '<span onclick="ObjectManager.displayItem(' + item.id + '); return false;">comment (<span class="commentCount"></span>)</span>'
			+ '<div class="comment"></div>'
		+ '</div>';

		if(ObjectManager.page == 'm')
		{
			msg += '<div class="object_menu">'
			+ '<span onclick="MapManager.locate('+ item.id +');"><i class="icon-screenshot"></i> locate</span><br/>'
			+ '<span onClick="set_delete(' + item.id + ');" data-toggle="modal" data-target="#confirmationModal"><i class="icon-remove"></i> delete</span><br/>'
			+ '<span onclick="init_update('+item.id+');"><i class="icon-edit"></i> updates</span>'
			+ '</div>';
		}
		msg += '<div class="clearfix"></div>'
		+ '</div>';
	
		return msg;
	};

	function displayDistance(distance)
	{
		var type = 'm';
		
		if(distance >= 1000)
		{
			distance /= 1000;
			type = 'km'; 
		}
		
		distance = Math.round(distance);
		
		if(type == 'km')
		{
			distance+= ' km';
		}
		else
		{
			distance+= ' m';
		}
		
		return distance;
	};

	function displayPhoto(uid, imgURL)
	{
		var array = imgURL.split(',');
		if(array[0] == 'empty')
			{
				imgURL = 'nophoto.png';
			}
		else
			{
				imgURL = uid+'/'+array[0];
			}
		return imgURL;
	};

	function displayDate(datetime)
	{
		
		return datetime;
	}
	
	/*
	 * PRIVATE
	 * Display comment from Disqus plugin
	 */
	this.displayItem = function(id)
	{
		$('contentBody').html('<img class="center" src="assets/img/ajax-loader.gif">');
		$('contentBody').load(BASEPATH+'pages/view_part/comment');
		/*
		var msg = displayListItem();
		$('contentBody').html(msg);
		displayComment();*/
	};
	
	/*
	 * PRIVATE
	 * Display comment counter from Disqus plugin
	 */
	function displayCommentCount(id)
	{
		$('#'+id+' .commentCount').html('<img class="center" src="'+BASEPATH+'assets/img/ajax-loader.gif">');
	    $('#'+id+' .commentCount').load(BASEPATH+'pages/view_part/commentCount');
	}
	
	/*
	 * public
	 * refresh one object and all objects if no id is defined
	 */
	/*
	 * Refresh object when geographical bounds are given
	 */
	this.refreshWithBounds = function(bounds)
	{
		getWithBounds(bounds);
	};
	
	this.refresh = function(mode, id, bounds)
	{
		switch(mode)
		{
			// load object with geographical bounds
			case 'bounds' : 
				console.log('refresh all objects'); 
				// get data from the BDD and do the next if success
		    	get('bounds', id, bounds);
		    break;
			// load only user item
			case 'user' : url = BASEPATH+'object/get_user/'; break;
			// load only one iten
			case 'item' : url = BASEPATH+'object/get_item/'+id; break;
		}
		/*
	    if (id === undefined) {
	    	// refresh all objects
	    	
	        // get data from the BDD and do the next if success
	    	get('bounds', id, bounds);
	    }
	    else {
	    	// refresh one object
	        console.log('refresh a single object - code to write');
	     // get data from the BDD and do the next if success
	    	//get(id);
	    }*/
	};
	
	/*
	 * PUBLIC
	 * Refresh distance for items
	 */
	this.refreshDistance = function(mapCenter)
	{
		for(i in items)
		{
			// update distance in the object
			items[i].setDistance(mapCenter);
			
			console.log(items[i].latlng);
			// Else : display distance
			//$('#'+items[i].id+' .distance').html(displayDistance(items[i].distance));
		}
		
		// If ordered by distance: display new distance and reorder list
		//displayList();
		console.log('refreshDistance() : success');
	};
	
	/*
	 *  PRIVATE
	 *  Update all objects list
	 */
	function displayList(sortBy)
	{
		// display the result
		if(page == 'm')
		{
			selector = '#mobject_list';
		}
		else
		{
			selector = '#list';
		}
		set_height(selector);
		
		if(sortBy == 'distance')
		{
			displayListByDistance(selector);
		}
		if(sortBy == 'price')
		{
			displayListByPrice(selector);
		}
		MapManager.displayOnMap();
	};
	
	function displayListByDistance(selector)
	{
		sortBy = 'distance';
		
		console.log(selector);
		
		var array = [];
		
		// get the map center
		var mapCenter = MapManager.getCenter();
		
		for(i in items)
		{
			items[i].setDistance(mapCenter);
			array.push([items[i], items[i].distance]);
		}
		
		array.sort(function(a,b) { return a[1] - b[1]; });
		//items.length = 0; // empty the array items, we cannot sort an "associative" array
		//items = [];
		
		$(selector).empty();
		
		var distCounter = 0;
		for(var i=0;i<array.length;i++)
		{
			var item = array[i][0];
			
			if(item.distance < MapManager.getPrecision() || page == 'm')
			{
				if(item.distance>200 && item.distance<500 && distCounter<200 && i!=0)
				{
					$(selector).append('<div class="division"><strong>- 200 m</strong></div>');
					distCounter = 200;
				}
				if(item.distance>500 && item.distance<MapManager.getPrecision() && distCounter<500 && i!=0)
				{
					$(selector).append('<div class="division"><strong>- 500 m</strong></div>');
					distCounter = 500;
				}
				
				var msg = displayListItem(item, page);
				// display item
				$(selector).append(msg);
				// display comment counter
				displayCommentCount(item.id);
			}
				
			//items[array[i][0].id] = array[i][0]; // repopulate the items array
		}
		$(selector).append('<div class="division"><strong>- '+displayDistance(MapManager.getPrecision())+'</strong></div>');
		
		console.log('displayListByDistance(): success');
	}
	
	function displayListByPrice(selector)
	{
		sortBy = 'price';
		
		var array = [];
		
		// get the map center
		var mapCenter = map.getCenter();
		
		for(i in items)
		{
			items[i].setDistance(mapCenter);
			array.push([items[i], items[i].price]);
		}
		
		array.sort(function(a,b) { return a[1] - b[1]; });
		
		$(selector).empty();
		
		var priceCounter = 0;
		for(var i=0;i<array.length;i++)
		{
			var item = array[i][0];
			if(item.distance < MapManager.getPrecision() || page == 'm')
			{
				if(item.price>10 && item.price<50 && priceCounter<50 && i!=0)
				{
					$(selector).append('<div class="division"><strong>- 10 euros</strong></div>');
					priceCounter = 50;
				}
				if(item.price>50 && priceCounter<100 && i!=0)
				{
					$(selector).append('<div class="division"><strong>- 50 euros</strong></div>');
					priceCounter = 100;
				}
				
				var msg = displayListItem(item, page);
				$(selector).append(msg);
			}
		}
		$(selector).append('<div class="division"><strong>- '+displayDistance(MapManager.getPrecision())+'</strong></div>');
	}

}